package variabilitysmelldetection.measurement.astvisitors;

import java.util.List;

import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.ArrayType;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;

import variabilitysmelldetection.measurement.models.AttributeItem;
import variabilitysmelldetection.measurement.models.ComponentItem;
import variabilitysmelldetection.measurement.models.MethodItem;


public class ClassVisitor extends ASTVisitor {
	private ComponentItem componentItem;
	
	public ClassVisitor(ComponentItem componentItem) {
		this.componentItem = componentItem;
	}
	
	public boolean visit(TypeDeclaration type) {
		
		Type superClass = type.getSuperclassType();
		if (superClass != null) {
			componentItem.setSuperClass(superClass.toString());			
		}
				
		return true;
	}
	
	@Override
	public boolean visit(MethodDeclaration method) {
		
		String methodName = MethodItem.getMethodNameWithParameters(method);
		List<String> parameters = MethodItem.getParameters(method);
		MethodItem m = new MethodItem(componentItem, methodName);
		Block body = method.getBody();
		if (body != null) {
			m.setSource(body.toString());
			if (m.getSource().contains("Super")) {
				m.setRefinement(true);
			}
		} else {
			m.setSource("");
		}
		m.setParametersTypes(parameters);
		
		
		componentItem.addMethod(m);
		return super.visit(method);
	} 
	
	@Override
	public boolean visit(FieldDeclaration field) {
		Type type = field.getType();
		boolean isPrimitive = type.isPrimitiveType();
		String typeName = type.toString();
		
		if (type.isArrayType()) {
			ArrayType arrayType = (ArrayType)field.getType();
			if (arrayType.getElementType().isPrimitiveType()) {
				isPrimitive = true; 
			} else {
				typeName = arrayType.getElementType().toString();
			}
		}

		Object o = field.fragments().get(0);
		String name = "";
		if(o instanceof VariableDeclarationFragment){
			VariableDeclarationFragment v = ((VariableDeclarationFragment) o);
			name = v.getName().toString();
		}
		
		AttributeItem att = new AttributeItem(componentItem, name);
		att.setSource(field.toString());
		att.setType(typeName);
		att.setPrimitiveType(isPrimitive);
//System.out.println(componentItem.getParentName()+"/"+componentItem.getName()+": "+att.getName()+" - "+att.getType()+" - "+att.isTypePrimitive()+" - "+att.isTypeArray());
		componentItem.addAttribute(att);
		return super.visit(field);
	} 
}